package cn.sunxiansheng.wx.controller;

import cn.sunxiansheng.wx.entity.AccessTokenResponse;
import cn.sunxiansheng.wx.entity.CodeAndState;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description: 微信登录Controller
 *
 * @Author sun
 * @Create 2025/1/13 16:26
 * @Version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/wx")
public class WxLoginController {

    @RequestMapping("/test")
    public String test() {
        return "test";
    }

    /**
     * appid
     */
    public static final String APPID = "";

    /**
     * secret
     */
    public static final String SECRET = "";

    /**
     * access_token_url
     */
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

    /**
     * 微信登录
     *
     * @param codeAndState 前端重定向后发来的code和state
     * @return openid
     */
    @RequestMapping("/login")
    public String login(@RequestBody CodeAndState codeAndState) {
        // 1.获取到code
        String code = codeAndState.getCode();
        // 2.使用code和secret以及appid换取token
        AccessTokenResponse accessToken = getAccessToken(APPID, SECRET, code);
        if (accessToken == null) {
            log.error("accessToken is null");
            return "null";
        }
        log.info("accessToken: {}", accessToken);
        return accessToken.getUnionid();
    }

    /**
     * 后端通过 code 获取 access_token
     *
     * @param appid  微信应用的 appid
     * @param secret 微信应用的 secret
     * @param code   后端已经获得的 code 参数
     * @return 返回封装的 AccessTokenResponse 对象
     */
    private AccessTokenResponse getAccessToken(String appid, String secret, String code) {
        // 构造请求 URL
        String url = String.format("%s?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                ACCESS_TOKEN_URL, appid, secret, code);

        // 创建 OkHttpClient 实例
        OkHttpClient client = new OkHttpClient();

        // 创建 Request 对象
        Request request = new Request.Builder()
                .url(url)
                .build();

        // 执行请求并处理响应
        try (Response response = client.newCall(request).execute()) {
            // 检查请求是否成功
            if (!response.isSuccessful()) {
                String responseBody = response.body() != null ? response.body().string() : "响应体为空";
                log.error("后端通过 code 获取 access_token 的请求失败，响应码：{}, 响应体：{}", response.code(), responseBody);
                return null;
            }

            // 打印成功的响应
            String jsonResponse = response.body() != null ? response.body().string() : "响应体为空";
            log.info("成功获取 access_token，响应：{}", jsonResponse);

            // 使用 Gson 解析 JSON 数据并封装成 AccessTokenResponse 对象
            Gson gson = new Gson();

            // 返回封装的对象
            return gson.fromJson(jsonResponse, AccessTokenResponse.class);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            // 返回 null 或者其他错误处理
            return null;
        }
    }
}